using System;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;

namespace FRecorder
{
    /// <summary> 编辑器GUI </summary>
    public class RecorderWindow : EditorWindow
    {
        /// <summary> 录制相机 </summary>
        Camera _camera;

        /// <summary> 设置 </summary>
        RecorderSettings _settings;

        /// <summary> 是否可以运行 | 是否可以运行 </summary>
        bool _isCanRun, _isRunRecorder;

        [MenuItem("Window/FTools/Recorder", priority = 2000)]
        static void OpenMenu()
        {
            var window = GetWindow<RecorderWindow>("快速录制");
            window.minSize = new Vector2(500, 210);
            window.maxSize = new Vector2(500, 210);
        }

        void OnEnable()
        {
            EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
        }

        void OnGUI()
        {
            _settings ??= RecorderSettings.ReadOrCreate();

            EditorGUILayout.Space();

            EditorGUILayout.BeginHorizontal("HelpBox");
            {
                DrawBaseSetting();
                DrawCaptureFrame();
            }
            EditorGUILayout.EndHorizontal();

            DrawRecordFrame();
        }

        /// <summary> 绘制基础设置 </summary>
        void DrawBaseSetting()
        {
            EditorGUILayout.BeginVertical();
            {
                EditorGUIUtility.labelWidth = 80;

                if (_camera == null)
                {
                    GUI.color = new Color(1, 0.6f, 0.6f);
                    _isCanRun = false;
                }
                else
                {
                    _isCanRun = true;
                }

                _camera = EditorGUILayout.ObjectField("录制相机", _camera, typeof(Camera), true) as Camera;
                GUI.color = Color.white;

                if (_camera == null)
                    _camera = Camera.main;

                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUIUtility.labelWidth = 82;
                    EditorGUILayout.BeginHorizontal();
                    {
                        var style = new GUIStyle("textfield");
                        EditorGUILayout.PrefixLabel("录制尺寸");
                        var size_x = (int)_settings.size.x;
                        var size_y = (int)_settings.size.y;
                        EditorGUI.BeginChangeCheck();
                        size_x = EditorGUILayout.IntField(size_x, style);
                        size_y = EditorGUILayout.IntField(size_y, style);
                        if (EditorGUI.EndChangeCheck())
                            _settings.size = new Vector2(size_x, size_y);
                    }
                    EditorGUILayout.EndHorizontal();

                    EditorGUIUtility.labelWidth = 79;
                    if (GUILayout.Button("Game 尺寸", GUILayout.Width(83)))
                    {
                        GUI.FocusControl(null);
                        _settings.size = Handles.GetMainGameViewSize();
                    }
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                {
                    _settings.format = EditorGUILayout.Popup("录制格式", _settings.format, new[] { "PNG", "JPG" });

                    if (_settings.alpha)
                        GUI.color = new Color(0.6f, 1, 0.6f);

                    if (GUILayout.Button("启用 Alpha", GUILayout.Width(83)))
                    {
                        GUI.FocusControl(null);
                        _settings.alpha = !_settings.alpha;
                    }

                    GUI.color = Color.white;
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                {
                    var tempName = EditorGUILayout.TextField("文件名称", _settings.fileName);
                    if (EditorGUI.EndChangeCheck() && IsValidFileName(tempName))
                        _settings.fileName = tempName;

                    var saveActive = EditorGUIUtility.IconContent("SaveActive");
                    saveActive.tooltip = "保存路径";
                    if (GUILayout.Button(saveActive, GUILayout.Width(83), GUILayout.Height(20)))
                    {
                        GUI.FocusControl(null);
                        var savePath = EditorUtility.OpenFolderPanel("保存路径", _settings.savePath, "");
                        if (!string.IsNullOrEmpty(savePath))
                            _settings.savePath = savePath;
                    }
                }
                EditorGUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                {
                    GUI.color = new Color(1, 1, 1, 0.5f);
                    var style = new GUIStyle("button");
                    style.alignment = TextAnchor.MiddleLeft;
                    style.stretchWidth = true;
                    if (GUILayout.Button(_settings.savePath, style))
                    {
                        GUI.FocusControl(null);
                        Application.OpenURL(_settings.savePath);
                    }
                    GUI.color = Color.white;
                }
                GUILayout.EndHorizontal();
            }
            EditorGUILayout.EndVertical();
        }

        /// <summary> 绘制抓帧 </summary>
        void DrawCaptureFrame()
        {
            GUI.enabled = _isCanRun;
            if (GUILayout.Button("截帧", GUILayout.Width(80), GUILayout.Height(82)))
            {
                GUI.FocusControl(null);

                ScreenshotDispose.SaveEnvironment(_camera);

                if (_settings.alpha)
                    ScreenshotDispose.SetAlphaEnvironment(_camera);

                var savePath = $"{_settings.savePath}/{_settings.fileName}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}";
                ScreenshotDispose.Screenshot(_camera, (int)_settings.size.x, (int)_settings.size.y, (ScreenshotDispose.Format)_settings.format, _settings.alpha, savePath);
                ScreenshotDispose.ResetEnvironment(_camera);
            }

            GUI.enabled = true;
        }

        /// <summary> 绘制录制帧 </summary>
        void DrawRecordFrame()
        {
            EditorGUILayout.BeginVertical("HelpBox");
            {
                _settings.frameRate = EditorGUILayout.Popup("录制帧率", _settings.frameRate, new[] { "12", "30", "60" });

                EditorGUIUtility.labelWidth = 82;
                EditorGUILayout.BeginHorizontal();
                {
                    var style = new GUIStyle("textfield");
                    EditorGUILayout.PrefixLabel("录制范围");

                    _settings.startFrame = EditorGUILayout.IntField(_settings.startFrame, style);
                    _settings.endFrame = EditorGUILayout.IntField(_settings.endFrame, style);
                }
                EditorGUILayout.EndHorizontal();

                GUI.enabled = _isCanRun;
                if (GUILayout.Button("录制", GUILayout.Height(40)))
                {
                    GUI.FocusControl(null);

                    ScreenshotDispose.SaveEnvironment(_camera);

                    if (_settings.alpha)
                        ScreenshotDispose.SetAlphaEnvironment(_camera);

                    _isRunRecorder = true;
                    EditorApplication.isPlaying = true;
                }

                GUI.enabled = true;
            }
            EditorGUILayout.EndVertical();
        }

        void OnDestroy()
        {
            RecorderSettings.SaveSettings(_settings);
            EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
            EditorApplication.isPlaying = false;
            EditorUtility.ClearProgressBar();
        }

        /// <summary> 播放状态改变时调用 </summary>
        void OnPlayModeStateChanged(PlayModeStateChange state)
        {
            if (state == PlayModeStateChange.EnteredPlayMode)
            {
                if (_isRunRecorder)
                    CreateRunRecorder(_settings);
            }
            else if (state == PlayModeStateChange.EnteredEditMode)
            {
                _isRunRecorder = false;
            }
        }

        /// <summary> 创建录制脚本 </summary>
        void CreateRunRecorder(RecorderSettings recorderSettings)
        {
            // settings 设置

             var go = new GameObject("[RunRecorder]");
            var runRecorder = go.AddComponent<RunRecorder>();
            runRecorder.format = ScreenshotDispose.Format.PNG;
            runRecorder.targetCamera = _camera;
            runRecorder.width = (int)recorderSettings.size.x;
            runRecorder.height = (int)recorderSettings.size.y;
            runRecorder.format = recorderSettings.format == 0 ? ScreenshotDispose.Format.PNG : ScreenshotDispose.Format.JPG;
            runRecorder.alpha = recorderSettings.alpha;

            switch (recorderSettings.frameRate)
            {
                case 0:
                    runRecorder.frameCount = 12;
                    break;
                case 1:
                    runRecorder.frameCount = 30;
                    break;
                case 2:
                    runRecorder.frameCount = 60;
                    break;
            }

            runRecorder.path = recorderSettings.savePath;
            runRecorder.fileName = recorderSettings.fileName;
            runRecorder.startFrame = recorderSettings.startFrame;
            runRecorder.endFrame = recorderSettings.endFrame;
            runRecorder.OnRecorderEnd = () => { };
        }

        /// <summary> 验证文件名 </summary>
        static bool IsValidFileName(string str)
        {
            // str  字符串

            var fileNameRegex = new Regex("^[^<>:\"/\\\\|?*\\x00-\\x1F]+$");
            return fileNameRegex.IsMatch(str);
        }
    }
}